/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { HvigorNode, HvigorPlugin } from '@ohos/hvigor';
import { Hvigor } from '@ohos/hvigor/src/base/external/core/hvigor';
import { DeserializationMode, PathConstants, TurboTransJsonPluginOptions, StringConstants } from './core';
import { initializeTypeHandlers } from './core/handlers/HandlerBootstrap';
import { JSONExecuteController } from './json-plugin/JSONExecuteController';

const PLUGIN_ID = StringConstants.PLUGIN_ID;
const DEFAULT_OPTIONS: TurboTransJsonPluginOptions = {
  ignoreModuleNames: [],
  scanDir: PathConstants.DEFAULT_SCAN_DIRS,
  deserializationMode: DeserializationMode.PERFORMANCE,
};

export function turboTransJsonPlugin(hvigor: Hvigor,
  options: TurboTransJsonPluginOptions = DEFAULT_OPTIONS): HvigorPlugin {
  return {
    pluginId: PLUGIN_ID,
    apply(node: HvigorNode): void {
      TurboTransJSONPluginManager.getInstance(hvigor).initialization(node, options);
    }
  };
}

class TurboTransJSONPluginManager {
  private static instance: TurboTransJSONPluginManager | null;
  private moduleExecuteControllers: Set<JSONExecuteController> = new Set(); // 每个模块对应的JSON插件

  private constructor(hvigor: Hvigor) {
    this.setupHvigorHooks(hvigor);
  }

  static getInstance(hvigor: Hvigor): TurboTransJSONPluginManager {
    if (!TurboTransJSONPluginManager.instance) {
      TurboTransJSONPluginManager.instance = new TurboTransJSONPluginManager(hvigor);
    }
    return TurboTransJSONPluginManager.instance;
  }

  initialization(node: HvigorNode, options: TurboTransJsonPluginOptions) {
    initializeTypeHandlers();
    node.subNodes(subNode => {
      const subNodeName = subNode.getNodeName();
      if (options.ignoreModuleNames.includes(subNodeName)) {
        return;
      }
      const executeController = new JSONExecuteController(subNode, options);
      this.moduleExecuteControllers.add(executeController);
    });
  }

  private setupHvigorHooks(hvigor: Hvigor) {
    hvigor.nodesEvaluated(() => {
      this.moduleExecuteControllers.forEach(controller => {
        controller.execute();
      });
    });

    hvigor.buildFinished(() => {
      this.moduleExecuteControllers.forEach(controller => {
        controller.compile();
      });
      this.moduleExecuteControllers.clear();
      TurboTransJSONPluginManager.instance = null;
    });
  }
}
